#include "BlockVertex.h"

// lib
#include <glm/glm.hpp>

// std
#include <cassert>

void BlockVertex::SetUv(const glm::vec2 &uv)
{
  this->uv = uv;
}

void BlockVertex::SetTexture(uint8_t x, uint8_t y)
{
  const int MaxTextureIndex = 63;
  const int MaxTextureIndexBits = 6;
  assert(x <= MaxTextureIndex && "Coordinate is out of bounds");
  assert(y <= MaxTextureIndex && "Coordinate is out of bounds");

  uint16_t uv = x | (y << MaxTextureIndexBits);
  assert(uv <= (MaxTextureIndex | MaxTextureIndex << MaxTextureIndexBits) && "Texture index is out of bounds");

  packed += uv;
}

void BlockVertex::SetAnimSize(uint16_t size)
{
  assert(size <= 32 && "Animation size is out of bounds");
  packed |= (size-1) << 12;
}

void BlockVertex::SetNormal(const glm::vec3 &normal)
{
  this->normal = normal;
}

void BlockVertex::SetOcclusionLevel(uint8_t occlusionLevel)
{
  assert(occlusionLevel < 4 && "The occlusion level is out of bounds");
  packed |= occlusionLevel << 17;
}

void BlockVertex::SetVertexLight(uint8_t light)
{
  light = std::clamp(light, uint8_t(0), uint8_t(15)); // Ensure light is within bounds [0, 15]
  packed |= light << 19;
}

glm::ivec3 BlockVertex::GetPosition() const
{
  // TODO
  return glm::ivec3{0};// {(data >> 9) & 0x1fu, data & 0x1ffu, (data >> 14) & 0x1fu};
}
